import { defineStore } from 'pinia';
import { Socket } from '../utils/socket';
import { KeyBoardControl, isMobile } from '../utils/utils';
import { io } from 'socket.io-client';
import { baseUrl } from '../utils/env';
import { useOnline } from '@vueuse/core';
import { ElNotification, ElMessage } from 'element-plus';
import { waveData } from '@/data/wave.js';
import { ElLoading } from 'element-plus';
import { TypeRoomInfo, TypeSoloInfo } from '../type/index';
import fetch from '@/api/fetch.js';
import { i18n } from '@/utils/i18n';
import GoEasy from '@/utils/goEasy';
const t = i18n.global.t;

const useAppStore = defineStore('app', {
    state: () => {
        return {
            isLogin: false,
            userInfo: {} as any,
            loadingBase: false as any,

            audioBase: false as any,
            keyBoardBase: false as any,

            ioBase: false as any,
            ioGetMessageCbList: [] as any,
            online: useOnline(),

            dgWsBase: false as any,
            dgInfo: {
                connection: false, // ws是否已连接
                status: false, // 是否已连接手机
                enable: false, // 是否启用DR功能
                clientId: '',
                targetId: '',
                qrCodeUrl: '', // 二维码
                strength: [0, 0], // 强度 通道a、b
                damageStrength: [0, 0], // 受到攻击时的强度
                gameoverStrength: [0, 0], // 游戏结束时的强度
                sort: [0, 0], // 软上限
                onConnected: () => { }, // 手机扫码连接成功回调
                gameOn: false, // 常驻开关
                damageOn: false, // 受伤开关
            },

            // 联机相关
            roomId: '',
            roomInfo: {} as TypeRoomInfo,
            soloInfo: {
                // 联机 - 1 vs 1 信息(仅solo模式使用)
                me: {},
                opponent: {},
            } as TypeSoloInfo,

            goEasyBase: new GoEasy(),
        };
    },
    actions: {
        // 中心信息
        showTopMessage(message: string, type: any = 'error') {
            ElMessage({
                message,
                type,
            });
        },
        // 右上角信息
        showMessage(
            message: string,
            p?: number,
            type?: 'success' | 'info' | 'warning' | 'error',
            duration?: number,
            title?: string
        ) {
            let position = 'top-right' as any;
            if (p == 1) position = 'top-left';
            if (p == 2) position = 'top-right';
            if (p == 3) position = 'bottom-left';
            if (p == 4) position = 'bottom-right';
            title = title || '提示';
            type = type || 'error';
            duration = duration || 2000;
            ElNotification({
                title,
                message,
                type,
                position,
                duration,
            });
        },
        // 音频操作
        initAudioBase(AudioBase: any) {
            this.audioBase = false;
            this.audioBase = new AudioBase();
        },
        playSound(name: string) {
            this.audioBase.playSound(name);
        },
        playBgm(name: string, rePlay = false) {
            this.audioBase.playBgm(name, rePlay);
        },
        stopBgm() {
            this.audioBase.stopBgm();
        },

        // 键盘操作
        initKeyBoardBase() {
            this.keyBoardBase = new KeyBoardControl();
        },
        loadKeyBoardAction(action = {}) {
            if (this.keyBoardBase) this.keyBoardBase.loadAction(action);
        },
        initKeyBoard(mode = '') {
            if (this.keyBoardBase) this.keyBoardBase.init(mode);
        },

        initIo() {
            // 初始化io
            console.log('初始化io');
            this.ioGetMessageCbList = [
                // 接受推送的事件列表
                {
                    action: 'matchSuccess', // 快速匹配成功 加入游戏房间
                    cb: () => { },
                    other: () => { },
                },
                {
                    action: 'updateFixedList', // 对局内事件 / 更新场地
                    cb: () => { },
                    other: () => { },
                },
                {
                    action: 'updateTargetBlock', // 对局内事件 / 更新当前块
                    cb: () => { },
                    other: () => { },
                },
                {
                    action: 'opponentGameOver', // 对局内事件 / 对手游戏结束
                    cb: () => { },
                    other: () => { },
                },
                {
                    action: 'opponentSendAtk', // 对局内事件 / 玩家发送攻击
                    cb: () => { },
                    other: () => { },
                },
                {
                    action: 'opponentAtkLineChange', // 对局内事件 / 玩家受击条变化
                    cb: () => { },
                    other: () => { },
                },
                {
                    action: 'opponentUpdatePlayerInfo', // 对局内事件 / 玩家信息更新
                    cb: () => { },
                    other: () => { },
                },
                {
                    action: 'playerLeaveRoom', // 对局内事件 / 玩家离开房间
                    cb: () => { },
                    other: () => { },
                },
            ];

            this.ioBase = io(baseUrl, {
                extraHeaders: {
                    token: 'miriru',
                },
                withCredentials: false, //  跨域请求时是否需要使用凭证
            });

            this.ioBase.on('pushUserMessage', (e: any) => {
                if (e && e.type == 'action' && e.action) {
                    let action = this.ioGetMessageCbList.find(
                        (item: any) => item.action == e.action
                    );
                    if (action && action.cb) action.cb(e.data); // 内部回调
                    if (action && action.other) action.other(e.data); // 外部注入回调
                } else console.log('接收到后端返回的数据', e);
            });

            this.ioBase.on('connect', () => {
                console.log('connect socket.id', this.ioBase.id);
                this.pushServerMessage(
                    'message',
                    '客户端已连接 socket.id:' + this.ioBase.id
                );
                this.ioUpdateUserInfo();
            });

            this.ioBase.on('connect_error', (reason: any) => {
                console.log('连接错误 socket.id reason', this.ioBase.id, reason);
            });

            this.ioBase.on('disconnect', (reason: any, details: any) => {
                console.log(
                    '断开连接 socket.id reason details',
                    this.ioBase.id,
                    reason,
                    details
                );
            });
        },
        pushServerMessage(action = '', data = {}) {
            // 推送指定action
            if (this.ioBase) {
                if (!this.online) {
                    this.showMessage('当前网络异常，请检查网络状态后重试');
                    return;
                }
                this.ioBase.emit('pushServerMessage', action, data);
            }
        },
        injectIoCb(action = '', cb: Function) {
            // io注入回调
            let actionItem = this.ioGetMessageCbList.find(
                (item: any) => item.action == action
            );
            if (actionItem) actionItem.other = cb;
        },
        // io注入用户信息 登录后调用
        ioUpdateUserInfo() {
            let { account, avatarUrl, name, userId } = this.userInfo;
            let data = {
                account,
                avatarUrl,
                name,
                userId,
            };
            console.log('ioUpdateUserInfo', data);
            this.pushServerMessage('updateUserInfo', data);
        },
        // 快速匹配
        joinMatch() {
            this.pushServerMessage('joinMatch');
        },
        // 退出匹配
        exitMatch() {
            this.pushServerMessage('exitMatch');
        },
        // 局内事件 - 当前块更新
        updateTargetBlock(data: any) {
            this.pushServerMessage('game/updateTargetBlock', data);
        },
        // 局内事件 - 固定块更新
        updateFixedList(data: any) {
            this.pushServerMessage('game/updateFixedList', data);
        },
        // 局内事件 - 游戏结束 - 离开房间并返回大厅
        gameOver(data: any) {
            this.pushServerMessage('game/gameOver', data);
        },
        // 局内事件 - 攻击
        gameSendAtk(data: any) {
            this.pushServerMessage('game/sendAtk', data);
        },
        // 局内事件 - 受击条发生变化
        updateAtkLine(data: any) {
            this.pushServerMessage('game/updateAtkLine', data);
        },
        // 局内事件 - 对局信息更新
        updatePlayerInfo(data: any) {
            this.pushServerMessage('game/updatePlayerInfo', data);
        },
        // 局内事件 - 退出快速匹配房间
        exitMatchRoom(data: any) {
            this.pushServerMessage('game/exitMatchRoom', data);
        },

        // ---------------------------------------- 郊狼相关 -------------------------------------------

        // 初始化郊狼websocket
        dgWsInit() {
            this.dgWsBase = new WebSocket('wss://ws.dungeon-lab.cn/');
            this.dgWsBase.onopen = () => {
                this.dgInfo.connection = true;
                console.log('郊狼 WebSocket连接已建立');
            };
            this.dgWsBase.onclose = () => {
                this.dgInfo.connection = false;
                this.dgInfo.status = false;
                this.dgInfo.enable = false;
                console.log('郊狼 WebSocket连接已断开');
            };
            this.dgWsBase.onmessage = (event: any) => {
                let message = null;
                try {
                    message = JSON.parse(event.data);
                } catch (e) {
                    console.log('DR-ws get message error', event.data);
                    return;
                }
                // 根据 message.type 进行不同的处理
                switch (message.type) {
                    case 'bind':
                        this.dgInfo.connection = true;
                        if (!message.targetId) {
                            // 初次连接获取targetId
                            this.dgInfo.clientId = message.clientId; // 获取 clientId
                            console.log('DR-ws 收到clientId: ' + message.clientId);
                            let qrCodeUrl =
                                'https://www.dungeon-lab.com/app-download.php#DGLAB-SOCKET#wss://ws.dungeon-lab.cn/' +
                                this.dgInfo.clientId;
                            this.dgInfo.qrCodeUrl = qrCodeUrl;
                        } else {
                            if (message.clientId != this.dgInfo.clientId) {
                                console.log(
                                    'DR-ws 收到clientId不正确的消息: ' + message.message
                                );
                                return;
                            }
                            this.dgInfo.targetId = message.targetId;
                            this.dgInfo.status = true;
                            console.log(
                                'DR-ws 收到targetWSId: ' +
                                message.targetId +
                                'msg: ' +
                                message.message
                            );
                            this.dgInfo.onConnected();
                            this.showMessage('DR-LAB 手机端连接成功', 2, 'success');
                        }
                        break;
                    case 'break':
                        //对方断开
                        if (message.targetId != this.dgInfo.targetId) return;
                        console.log('DR-ws 手机端已断开: ' + message.message);
                        this.dgInfo.status = false;
                        this.showMessage('DR-LAB 手机端已断开 请检查连接');
                        break;
                    case 'error':
                        if (message.targetId != this.dgInfo.targetId) return;
                        console.log('DR-ws error: ' + message.message);
                        this.dgInfo.status = false;
                        this.showMessage('DR-LAB 手机端连接错误 请检查连接');
                        break;
                    case 'msg':
                        console.log('DR-ws 消息同步：' + JSON.stringify(message.message));
                        if (message.message.includes('strength')) {
                            // 同步强度
                            const numbers = message.message.match(/\d+/g).map(Number);
                            this.dgInfo.strength[0] = numbers[0];
                            this.dgInfo.strength[1] = numbers[1];
                            this.dgInfo.sort[0] = numbers[2];
                            this.dgInfo.sort[1] = numbers[3];
                        } else if (message.message.includes('feedback')) {
                            // showSuccessToast(feedBackMsg[message.message]);
                            console.log('DR-ws feedback 消息同步：:', message);
                        }
                        break;
                    case 'heartbeat':
                        console.log('DR-ws 收到心跳');
                        break;
                    default:
                        console.log('DR-ws 收到其他类型消息：' + JSON.stringify(message));
                        break;
                }
            };
        },
        dgSwitch() {
            if (!this.dgInfo.enable && !this.online) {
                // 启用
                this.showMessage('当前网络异常，请检查网络状态后重试');
                return;
            }
            this.dgInfo.enable = !this.dgInfo.enable;
            if (this.dgInfo.enable) {
                this.dgWsInit();
            } else {
                this.dgInfo.connection = false;
                this.dgInfo.status = false;
                this.dgWsBase.close();
            }
        },
        dgSend(val: any) {
            if (!this.dgInfo.connection || !this.dgInfo.status)
                return this.showMessage('当前网络异常，请尝试刷新页面重试');
            if (!this.dgInfo.enable) return;
            console.log('dgSend val', val);
            let text = JSON.stringify(val);
            this.dgWsBase.send(text);
        },
        // send 设置强度
        dgSetStrength(channel: number, val: number) {
            // 通道 强度
            let { clientId = '', targetId = '' } = this.dgInfo;
            this.dgSend({
                type: 4,
                message: `strength-${channel}+2+${val}`,
                clientId,
                targetId,
            });
        },
        // send 发送波形
        dgSendWave(channel: number, time: number) {
            // 通道 时间(秒)
            let { clientId = '', targetId = '' } = this.dgInfo;
            let data = {
                clientId,
                targetId,
                type: 'clientMsg',
                time,
                channel: channel === 1 ? 'A' : 'B',
                message: (channel === 1 ? 'A' : 'B') + ':' + waveData[2],
            } as any;
            this.dgSend(data);
        },
        // 清除当前播放的波形
        clearWave() {
            let { clientId = '', targetId = '' } = this.dgInfo;
            const data1 = { type: 4, message: 'clear-1', clientId, targetId };
            this.dgSend(data1);
            const data2 = { type: 4, message: 'clear-2', clientId, targetId };
            this.dgSend(data2);
        },

        // --------------------------------------- 登录相关 ------------------------------------------
        updateUserInfo(data: any) {
            console.log('updateUserInfo', data);
            this.userInfo = data;
        },

        // 退出登录
        logout() {
            // 这里可以添加请求退出登录的接口
            fetch('logout', {
                account: this.userInfo.account,
            }) // 假设有一个退出登录的接口
                .then(() => {
                    this.userInfo = null; // 清除用户信息
                    this.isLogin = false; // 重置登录状态
                    localStorage.removeItem('qlKey'); // 清除缓存中的 qlKey
                    this.showTopMessage(t('me.logoutSuccess'), 'success'); // 使用 t 函数显示退出登录消息
                })
                .catch((err: any) => {
                    console.error('退出登录失败', err);
                    this.showTopMessage(t('me.logoutFailed'), 'error'); // 使用 t 函数显示退出登录失败消息
                });
        },
    },
});

export default useAppStore;
